/**
* Copyright (c) By zengqh.
*
* This program is just for fun or demo, in the hope that it  
* will be useful, you can redistribute it and/or modify freely.
*
* Time: 2013/02/18
* File: enn_plane.h
**/

#pragma once

#include "enn_vector3.h"

namespace enn
{
/// Surface in three-dimensional space.
class Plane
{
public:
	/// Construct undefined.
	Plane()
	{
	}

	/// Copy-construct from another plane.
	Plane(const Plane& plane) :
	normal_(plane.normal_),
		intercept_(plane.intercept_)
	{
	}

	/// Construct from 3 vertices.
	Plane(const vec3f& v0, const vec3f& v1, const vec3f& v2)
	{
		Define(v0, v1, v2);
	}

	/// Construct from a normal vector and a point on the plane.
	Plane(const vec3f& normal, const vec3f& point)
	{
		Define(normal, point);
	}

	/// Define from 3 vertices.
	void Define(const vec3f& v0, const vec3f& v1, const vec3f& v2)
	{
		vec3f dist1 = v1 - v0;
		vec3f dist2 = v2 - v0;

		normal_ = (dist1.CrossProduct(dist2)).Normalized();
		absNormal_ = vec3f(Abs(normal_.x_), Abs(normal_.y_), Abs(normal_.z_));
		intercept_ = normal_.DotProduct(v0);
	}

	/// Define from a normal and a point.
	void Define(const vec3f& normal, const vec3f& point)
	{
		normal_ = normal;
		absNormal_ = vec3f(Abs(normal_.x_), Abs(normal_.y_), Abs(normal_.z_));
		intercept_ = normal_.DotProduct(point);
	}

	/// Return signed distance to a point.
	float Distance(const vec3f& point) const { return normal_.DotProduct(point) - intercept_; }

	/// Plane normal.
	vec3f normal_;
	/// Plane absolute normal.
	vec3f absNormal_;
	/// Plane intercept parameter.
	float intercept_;
};

}